/**
 * 深圳奥联信息安全技术有限公司 2018-01-17
 */

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 类 EYIBCLib.
 */
public class EYIBCLib implements EYIBCConstants{
	
	private static final EYIBCLib instance  = new EYIBCLib();
	
	private static boolean libLoaded = false;
		
	public static long IBC_ERROR_UNDER = -30000;
	/** 引擎句柄 */
	public long m_libContext = 0;
	
	/** 参数句柄，会被覆盖. */
	public long m_ibcParamCtx = 0;
	
	/**
	 * 实例化EYIBCLib，并加载相应的库
	 */
	private EYIBCLib() {}
	
	static
	{
		try{
			System.loadLibrary("eyibc");
			System.loadLibrary("eyibc4j");
			initEYIBC();
			libLoaded = true;
		}
	    catch (UnsatisfiedLinkError e)
	    {
	    	System.out.println("Could not load eyibc4j library!");
	    	System.out.println(e.getMessage());
	    }  
	}
	
	public static boolean isIBCError(long iErrorCode)
	{
		return (iErrorCode > IBC_ERROR_UNDER && iErrorCode <=0);
	}
	/**
	 * 获取EYIBCLib的实例，您总是应该通过此函数来得到EYIBCLib的实例.
	 *
	 * @return EYIBCLib实例
	 */
	public static EYIBCLib getInstance()
	{
		if (libLoaded)
			return instance;
		else
			return null;
	}
	
	/**
	 * 加载证书.
	 *
	 * @param paramFileName 证书文件
	 * @throws EYIBCException 异常
	 */
	public synchronized void loadContext(String paramFileName) throws EYIBCException
	{
		if (m_libContext == 0) {
			m_libContext = createLibCtx();
			setLibCtx(m_libContext);
		}
		if (m_ibcParamCtx == 0)
			m_ibcParamCtx = loadIBCParamIntoLibCtx(m_libContext, paramFileName);
	}
	
	/**
	 * 创建引擎句柄.
	 *
	 * @return 引擎句柄
	 * @see #DestroyLibCtx(long)
	 * @throws EYIBCException 异常
	 */
	public native long createLibCtx() throws EYIBCException;
	
	/**
	 * 设置引擎句柄
	 *
	 * @param libCtxHandle新的引擎句柄
	 * @see #createLibCtx()
	 * @throws EYIBCException 异常
	 */
	public native void setLibCtx(long libCtxHandle) throws EYIBCException;
	
	/**
	 * 设置根证.
	 *
	 * @param libCtx 引擎句柄
	 * @param rootCertArray 根证数组
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int setRootCert(long libCtx, String[] rootCertArray) throws EYIBCException;
	
	/**
	 * 加载参数对象，并加入到引擎中
	 * @param libContext 引擎句柄
	 * @param paramData 参数内容
	 * @param paramDataLength 参数内容长度
	 * @return 参数对象
	 * @throws EYIBCException
	 */
	public native long loadIBCParamContentIntoLibCtx(
			long libContext,
			byte[] paramData,
			int paramDataLength
			) throws EYIBCException;
			
	/**
	 * 加载参数文件，并加入到引擎中.
	 *
	 * @param libContext 引擎句柄
	 * @param paramFileName 参数文件名
	 * @return 参数句柄
	 * @see #createLibCtx()
	 * @see #createPrvKeyObjectFromFile(long, String, String)
	 * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int)
	 * @throws EYIBCException 异常
	 */
	public native long loadIBCParamIntoLibCtx(
			long libContext,
			String paramFileName
			) throws EYIBCException;
	
	
	/**
	 * 从参数文件中创建IBC参数对象
	 * @param paramFileName 参数文件
	 * @return 参数对象
	 */
	public long createIBCParamObjectFromFile(String paramFileName) throws EYIBCException
	{
		return CreateIBCParamObjectFromFile(paramFileName);
	}
	
	public native long CreateIBCParamObjectFromFile(String paramFileName) throws EYIBCException;
	
	/**
	 * 释放参数句柄.
	 *
	 * @param ibcParamContext 参数句柄
	 * @see #loadIBCParamIntoLibCtx(long, String)
	 */
	public void destroyIBCParamObject(
			long ibcParamContext
			) 
	{
		DestroyIBCParamObject(ibcParamContext);
	}
	
	public native void DestroyIBCParamObject(
			long ibcParamContext
			);
	
	/**
	 * 释放引擎句柄.
	 *
	 * @param libContext 引擎句柄
	 * @see #createLibCtx()
	 * @throws EYIBCException 异常
	 */	
	public void destroyLibCtx(
			long libContext
			)
	{
		DestroyLibCtx(libContext);
	}
	
	public native void DestroyLibCtx(
			long libContext
			);
	
	/**
	 * 根据参数句柄验证签名数据
	 *
	 * @param random 随机值
	 * @param randomLen 随机值长度
	 * @param response 响应值
	 * @param responseLen 响应值长度
	 * @param ibcParamContext 参数句柄
	 * @return 1为验签成功
	 * @throws EYIBCException 异常
	 */
	public native int vertifySignDataWithCtx(
			byte[] 	random, 
			int 	randomLen, 
			byte[] 	response, 
			int 	responseLen, 
			long 	ibcParamContext
		) throws EYIBCException;
	
	/**
	 * 根据参数句柄验证签名数据扩展
	 *
	 * @param random 随机值
	 * @param randomLen 随机值长度
	 * @param response 响应值
	 * @param responseLen 响应值长度
	 * @param ibcParamContext 参数句柄
	 * @param flags flags 保留值
	 * @return 1为验签成功
	 * @throws EYIBCException 异常
	 */
	public native int vertifySignDataWithCtx2(
			byte[] 	random, 
			int 	randomLen, 
			byte[] 	response, 
			int 	responseLen, 
			long 	ibcParamContext,
			int		flags
		) throws EYIBCException;
	
	/**
	 * 获取响应属性值.
	 *
	 * @param response 响应值
	 * @param responseLen 响应值长度
	 * @param attrType 属性类型
	 * @param attrData 属性值
	 * @param attrDataLen 属性值长度
	 * @param ibcParamContext 参数对象
	 * @return 结果
	 * @throws EYIBCException 异常
	 */
	public native int getResponseAttributeWithCtx(
			byte[] 	response, 
			int 	responseLen, 
			int 	attrType, 
			byte[] 	attrData, 
			int[] 	attrDataLen,
			long 	ibcParamContext
		) throws EYIBCException;
	
	/**
	 * 获取随机数.
	 *
	 * @param randomBuf 存放随机数的数组，外面分配内容
	 * @param randomLen 生成随机数的长度，不能大于数组的长度
	 * @return 兼容未用
	 * @throws EYIBCException 异常
	 */
	public native int getRandom(
			byte[] 	randomBuf, 
			int 	randomLen
		) throws EYIBCException;
	
	/**
	 * 根据随机值生成挑战值
	 *
	 * @param 挑战值
	 * @param 挑战值长度
	 * @param 随机值
	 * @param 随机值长度
	 * @return 
	 * @throws EYIBCException 异常
	 */
	public native int getChallengeByRandom(
			byte[] 	challengeBuf, 
			int[] 	challengeLen, 
			byte[] 	random, 
			int 	randomLen
		) throws EYIBCException;
		
	@Deprecated
	public native int signChallengeData(
			byte[]  identId,
			int 	identIdLen,
			byte[] 	pinPwd,
			int 	pinPwdLen,
			byte[] 	challengeData, 
			int 	chalDataLen, 
			byte[] 	responseData, 
			int[] 	respDataLen
		) throws EYIBCException;
	
	/**
	 * 校验响应值
	 *
	 * @param 响应值
	 * @param 响应值长度
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int checkResponse(
			byte[] response, 
			int responseLen
		) throws EYIBCException;
	
	/**
	 * Vertify sign data.
	 *
	 * @param random the random
	 * @param randomLen the random len
	 * @param response the response
	 * @param responseLen the response len
	 * @param fileName the file name
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int vertifySignData(
			byte[] 	random, 
			int 	randomLen, 
			byte[] 	response, 
			int 	responseLen, 
			String 	fileName
		) throws EYIBCException;
	
	/**
	 * DEBASE64
	 *
	 * @param base64Data BASE64数据
	 * @param base64DataLen BASE64数据长度
	 * @param rawData DEBASE64结果
	 * @param rawDataLen DEBASE64结果长度
	 * @return 
	 * @throws EYIBCException 异常
	 */
	public native int deBase64Data(
			byte[] 	base64Data, 
			int 	base64DataLen, 
			byte[] 	rawData, 
			int[] 	rawDataLen
		) throws EYIBCException;
	
	public native int deBase64ToFile(
			byte[] 	base64Data, 
			int 	base64DataLen, 
			String 	outFile
		) throws EYIBCException;
	
	public native int deBase64FileToFile(
			String 	inFile,
			String 	outFile
		) throws EYIBCException;
	
	/**
	 * Gets the response attribute.
	 *
	 * @param response the response
	 * @param responseLen the response len
	 * @param attrType the attr type
	 * @param attrData the attr data
	 * @param attrDataLen the attr data len
	 * @param fileName the file name
	 * @return the response attribute
	 * @throws EYIBCException 异常
	 */
	public native int getResponseAttribute(
			byte[] 	response, 
			int 	responseLen, 
			int 	attrType, 
			byte[] 	attrData, 
			int[] 	attrDataLen,
			String 	fileName
		) throws EYIBCException;
	
	/**
	 * Veritfy pki response.
	 *
	 * @param random the random
	 * @param randomLen the random len
	 * @param response the response
	 * @param responseLen the response len
	 * @param rootCertArray the root cert array
	 * @param crlArray the crl array
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int veritfyPKIResponse(
			byte[] 	random, 
			int 	randomLen, 
			byte[] 	response, 
			int 	responseLen,
			String[] rootCertArray, 
			String[] crlArray
		) throws EYIBCException;

	
	/*For ZDM*/
	/**
	 * Encap s mail.
	 *
	 * @param nFormat the n format
	 * @param inFile the in file
	 * @param outFile the out file
	 * @param paramFile the param file
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param certList the cert list
	 * @param appFile the app file
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int encapSMail(
			int 	nFormat, 
			String 	inFile, 
			String 	outFile, 
			String 	paramFile, 
			byte[] 	keyData, 
			int 	keyLen, 
			byte[] 	pass, 
			int 	passLen, 
			int[] 	certList, 
			String 	appFile
		) throws EYIBCException;
	
	/**
	 * Sign encap s mail.
	 *
	 * @param nFormat the n format
	 * @param inFile the in file
	 * @param outFile the out file
	 * @param paramFile the param file
	 * @param signature the signature
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param certList the cert list
	 * @param appFile the app file
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int signEncapSMail(
			int 	nFormat, 
			String 	inFile, 
			String 	outFile, 
			String 	paramFile, 
			String 	signature, 
			byte[] 	pass, 
			int 	passLen, 
			int[] 	certList, 
			String 	appFile
		) throws EYIBCException;
	
	/**
	 * Decap s mail.
	 *
	 * @param inFile the in file
	 * @param outFile the out file
	 * @param paramFile the param file
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int decapSMail(
			String 	inFile, 
			String 	outFile, 
			String 	paramFile, 
			byte[] 	keyData, 
			int 	keyLen,
			byte[] 	pass,
			int 	passLen
		) throws EYIBCException;
	
	/**
	 * 从内存中创建私钥句柄
	 *
	 * @param libCtx 引擎句柄
	 * @param ctx 返回的私钥句柄，new long[1]
	 * @param keyMem 私钥数据
	 * @param keyLen 私钥数据的长度
	 * @param passwd 私钥保护口令
	 * @param passwdLen 私钥保护口令长度
	 * @return 兼容未用
	 * @see #createLibCtx()
	 * @see #loadIBCParamIntoLibCtx(long, String)
	 * @see #createPrvKeyObjectFromFile(long, String, String)
	 * @see #DestroyIBCParamObject(long)
	 * @see #getPrivateBasicID(long)
	 * @see #getPrivateDomainAndSerial(long, int[])
	 * @see #getPrivateValidTime(long, long[], long[])
	 * @throws EYIBCException 异常
	 */
	public native int createPrvKeyObjectFromMem(
			long		libCtx, 
			long[]	ctx, 
			byte[] 	keyMem, 
			int 	keyLen, 
			byte[] 	passwd, 
			int 	passwdLen
			) throws EYIBCException;
	
	/**
	 * 从内存中创建私钥句柄扩展(裸密钥)
	 *
	 * @param libCtx 引擎句柄
	 * @param paramCtx 参数句柄
	 * @param ctx 返回的私钥句柄，new long[1]
	 * @param keyMem 私钥数据
	 * @param keyLen 私钥数据的长度
	 * @param ID 私钥标识
	 * @param IDLen 私钥标识长度
	 * @return 兼容未用
	 * @see #createLibCtx()
	 * @see #loadIBCParamIntoLibCtx(long, String)
	 * @see #createPrvKeyObjectFromFile(long, String, String)
	 * @see #DestroyIBCParamObject(long)
	 * @see #getPrivateBasicID(long)
	 * @see #getPrivateDomainAndSerial(long, int[])
	 * @see #getPrivateValidTime(long, long[], long[])
	 * @throws EYIBCException 异常
	 */
	public native int createPrvKeyObjectFromMemEx(
			long		libCtx, 
			long		paramCtx,
			long[]	ctx, 
			byte[] 	keyMem, 
			int 	keyLen, 
			byte[] 	passwd, 
			int 	passwdLen
			) throws EYIBCException;
	
	/**
	 * Gm p7 reader.
	 *
	 * @param paramFile the param file
	 * @param inFile the in file
	 * @param outFile the out file
	 * @param recpList the recp list
	 * @param recpLen the recp len
	 * @param signList the sign list
	 * @param signLen the sign len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmP7Reader(
			String 	paramFile, 
			String 	inFile, 
			String 	outFile, 
			byte[] 	recpList, 
			int[] 	recpLen, 
			byte[] 	signList, 
			int[] 	signLen, 
			byte[] 	pass, 
			int 	passLen, 
			byte[] 	keyData, 
			int 	keyLen
		) throws EYIBCException;
	
	/**
	 * Gm p7 reader from mem.
	 *
	 * @param paramFile the param file
	 * @param inDataBuf the in data buf
	 * @param inDataBufLen the in data buf len
	 * @param outFile the out file
	 * @param recpList the recp list
	 * @param recpLen the recp len
	 * @param signList the sign list
	 * @param signLen the sign len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmP7ReaderFromMem(
			String 	paramFile, 
			byte[] 	inDataBuf, 
			int 	inDataBufLen, 
			String 	outFile, 
			byte[] 	recpList, 
			int[] 	recpLen, 
			byte[] 	signList, 
			int[] 	signLen, 
			byte[] 	pass, 
			int 	passLen, 
			byte[] 	keyData, 
			int 	keyLen
		) throws EYIBCException;
	
	/*operator GMSTREAM*/
	/**
	 * Gm open file stream.
	 *
	 * @param streamObj the stream obj
	 * @param fileName the file name
	 * @param mode the mode
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmOpenFileStream(
			int[] streamObj,
			String fileName,
			int mode
	) throws EYIBCException;
	
	/**
	 * Gm open mem stream.
	 *
	 * @param streamObj the stream obj
	 * @param buf the buf
	 * @param bufLen the buf len
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmOpenMemStream(
			int[] streamObj,
			byte[] buf,
			int bufLen
	) throws EYIBCException;
	
	/**
	 * Gm stream size.
	 *
	 * @param streamObj the stream obj
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmStreamSize(
			long streamObj
	) throws EYIBCException;
	
	/**
	 * Gm close stream.
	 *
	 * @param streamObj the stream obj
	 * @param buf the buf
	 * @param writeBack the write back
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmCloseStream(
			long streamObj,
			byte[] buf,
			int writeBack
	) throws EYIBCException;
	
	
	/*For ZDM Extend in stream operation*/
	/**
	 * Encap s mail stream.
	 *
	 * @param nFormat the n format
	 * @param inStream the in stream
	 * @param outStream the out stream
	 * @param ibcParamContext the ibc param context
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param certList the cert list
	 * @param configFile the config file
	 * @param cfgLen the cfg len
	 * @param nFlags the n flags
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int encapSMailStream(
			int 	nFormat,
			long 	inStream,
			long 	outStream,
			long 	ibcParamContext, 
			byte[] 	keyData, 
			int 	keyLen, 
			byte[] 	pass, 
			int 	passLen, 
			int[] 	certList, 
			byte[] 	configFile,
			int 	cfgLen,
			int		nFlags
		) throws EYIBCException;
	
	/*For decryption in memory operation*/
	/**
	 * Gm p7 reader ex2.
	 *
	 * @param libCtxHandle the lib ctx handle
	 * @param inStream the in stream
	 * @param outStream the out stream
	 * @param recpList the recp list
	 * @param recpLen the recp len
	 * @param signList the sign list
	 * @param signLen the sign len
	 * @param pass the pass
	 * @param passLen the pass len
	 * @param keyData the key data
	 * @param keyLen the key len
	 * @param inAuxFile the in aux file
	 * @return the int
	 * @throws EYIBCException 异常
	 */
	public native int gmP7ReaderEx2(
			long 	libCtxHandle, 
			long 	inStream,
			long 	outStream,			
			byte[] 	recpList, 
			int[] 	recpLen, 
			byte[] 	signList, 
			int[] 	signLen, 
			byte[] 	pass, 
			int 	passLen, 
			byte[] 	keyData, 
			int 	keyLen,
			String 	inAuxFile
		) throws EYIBCException;	
	
	/*getIBCParamInfo*/
	/**
	 * 获取参数内容对应的信息.
	 *
	 * @param paramContent 参数内容
	 * @param paramContentSize 参数内容的长度
	 * @param domain 参数域
	 * @param version 参数版本
	 * @return 兼容未用
	 * @see #loadIBCParamIntoLibCtx(long, String)
	 * @throws EYIBCException 异常
	 */
	public native int getIBCParamInfo(
			byte[]  paramContent,
			int     paramContentSize,
			byte[] 	domain,			
			int[] 	version
		) throws EYIBCException;
		
	/**
	 * Gets the bytes from file.
	 *
	 * @param f the f
	 * @return the bytes from file
	 */
	public static byte[] getBytesFromFile(File f) {
		if (f == null) {
			return null;
		}
		try {
			FileInputStream stream = new FileInputStream(f);
			ByteArrayOutputStream out = new ByteArrayOutputStream(1000);
			byte[] b = new byte[1000];
			int n;
			while ((n = stream.read(b)) != -1)
				out.write(b, 0, n);
			stream.close();
			out.close();
			return out.toByteArray();
		} catch (IOException e) {
		}
		return null;
	}
	
	/**
	 * Save bytes to file.
	 *
	 * @param data the data
	 * @param dataLen the data len
	 * @param outputFile the output file
	 * @return the file
	 */
	public static File saveBytesToFile(byte[] data, int dataLen, String outputFile) {
		File retFile = null;
		BufferedOutputStream stream = null;
		try {
			retFile = new File(outputFile);
			FileOutputStream fstream = new FileOutputStream(retFile);
			stream = new BufferedOutputStream(fstream);
			stream.write(data, 0, dataLen);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return retFile;
	}

  /**
   * 从文件中创建私钥句柄.
   *
   * @param libCtx 引擎句柄
   * @param fileName 私钥文件名
   * @param password 私钥保护口令
   * @return 私钥句柄
   * @see #createLibCtx()
   * @see #loadIBCParamIntoLibCtx(long, String)
   * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int)
   * @see #DestroyPrvKeyObject(long)
   * @see #getPrivateBasicID(long)
   * @see #getPrivateDomainAndSerial(long, int[])
   * @see #getPrivateValidTime(long, long[], long[])
   * @throws EYIBCException 异常
   */
  public native long createPrvKeyObjectFromFile(long libCtx, String fileName, String password)throws EYIBCException;
  
  /**
   * 释放私钥句柄
   *
   * @param prvKeyObject 私钥句柄
   * @see #createPrvKeyObjectFromFile(long, String, String)
   * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int)
   */
  public native void DestroyPrvKeyObject(long privateCtx);
  
  /**
   * 用SM9算法签名私钥.
   *
   * @param privateCtx 私钥句柄
   * @param inBuf 需要签名的数据
   * @return the 签名结果
   * @see #cryptVerifySignData(long, byte[], byte[], byte[])
   * @throws EYIBCException 异常
   */
  public native byte[] cryptSignData(long privateCtx, byte[] inBuf) throws EYIBCException;

  /**
   * 用SM9算法验签数据
   *
   * @param ibcParamCtx 参数句柄
   * @param signerBuf 签名结果
   * @param inBuf 原始数据
   * @param signer 签名人，对应{@link #cryptSignData(long, byte[])}中私钥句柄的私钥标识
   * @return 返回结果<br>1成功，其它失败
   * @see #cryptSignData(long, byte[])
   */
  public native int cryptVerifySignData(long ibcParamCtx, byte[] signerBuf, byte[] inBuf,byte[] signer);
  
  /**
   * 用SM9算法加密数据.
   *
   * @param ibcParamCtx 参数句柄
   * @param Alg 算法
   * @param recpList 可解密人标识
   * @param inBuf 需要加密的数据
   * @return 加密后的数据
   * @see #cryptImportData(long, byte[])
   * @throws EYIBCException 异常   * 
   */
  public native byte[] cryptExportData(long ibcParamCtx, int Alg, String recpList, byte[] inBuf) throws EYIBCException;
  
  /**
   * 用SM9算法解密数据
   *
   * @param privateCtx 私钥句柄
   * @param inBuf 需要解密的数据
   * @return 解密后的数据
   * @see #cryptImportData(long, byte[])
   * @throws EYIBCException 异常
   */
  public native byte[] cryptImportData(long privateCtx, byte[] inBuf) throws EYIBCException;
  
  /**
   * 用对称算法进行加密.
   *
   * @param alg 算法
   * @param key 对称口令
   * @param iv 向量，可以为null
   * @param inBuf 需要加密的数据
   * @param flags 保留值，请传0
   * @return 加密后的数据
   * @see #cryptDecrypt(int, byte[], byte[], byte[], int)
   * @throws EYIBCException 异常
   */
  public native byte[] cryptEncrypt(int alg, byte[] key, byte[] iv, byte[] inBuf, int flags) throws EYIBCException;
  
  /**
   * 用对称算法进行解密
   *
   * @param alg 算法
   * @param key 对称口令
   * @param iv 向量，可以为null
   * @param inBuf 需要解密的数据
   * @param flags 保留值，请传0
   * @return 解密后的数据
   * @see #cryptEncrypt(int, byte[], byte[], byte[], int)
   * @throws EYIBCException 异常
   */
  public native byte[] cryptDecrypt(int alg, byte[] key, byte[] iv, byte[] inBuf, int flags) throws EYIBCException;
 
  /**
   * 获取私钥的参数域和版本
   *
   * @param privateCtx 私钥句柄
   * @param serial 参数版本
   * @return 参数域
   * @see #createPrvKeyObjectFromFile(long, String, String)
   * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int)
   * @throws EYIBCException 异常
   */
  public native byte[] getPrivateDomainAndSerial(long privateCtx, int[] serial) throws EYIBCException;
  
  /**
   * 获取私钥的基本标识
   *
   * @param privateCtx 私钥句柄
   * @return 基本标识
   * @see #createPrvKeyObjectFromFile(long, String, String)
   * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int) 
   * @throws EYIBCException 异常
   */
  public native byte[] getPrivateBasicID(long privateCtx) throws EYIBCException;
  
  /**
   * 获取私钥的有效期
   *
   * @param privateCtx 私钥句柄
   * @param nBefore 有效期开始时间，如要转化为Date，请*1000，如 new Date(nBefore[0]*1000);
   * @param nAfter 有效期结束时间，如要转化为Date，请*1000，如 new Date(nBefore[0]*1000);
   * @see #createPrvKeyObjectFromFile(long, String, String)
   * @see #createPrvKeyObjectFromMem(long, long[], byte[], int, byte[], int)
   * @throws EYIBCException 异常
   */
  public native void getPrivateValidTime(long privateCtx, long[] nBefore, long[] nAfter) throws EYIBCException;
  
  public native byte[] genHashData(byte[] inputData, int hashType) throws EYIBCException;
  					 

	private native void p7cryptDecryptFile(byte[] keyBuf, int keyLen,
			String inputFileName, String outputFileName) throws EYIBCException;

	/**
	 * 对称解密p7文件
	 * 
	 * @param keyBuf
	 *            对称密钥
	 * @param keyLen
	 *            对称密钥长度
	 * @param inputFileName
	 *            输入的文件名
	 * @param outputFileName
	 *            解密后的文件名
	 * @see #p7cryptEncryptFile(int, byte[], int, String, String)
	 */
	public void P7CryptDecryptFile(byte[] keyBuf, int keyLen,
			String inputFileName, String outputFileName)
			throws EYIBCException {
		p7cryptDecryptFile(keyBuf, keyLen, inputFileName, outputFileName);
	}

	private native void p7cryptEncryptFile(int algType, byte[] keyBuf,
			int keyLen, String inputFileName, String outputFileName)
			throws EYIBCException;

	/**
	 * 对称加密p7文件
	 * 
	 * @param algType
	 *            算法类型 
	 * @param keyBuf
	 *            加密密钥
	 * @param keyLen
	 *            加密密钥长度
	 * @param inputFileName
	 *            需要加密的文件
	 * @param outputFileName
	 *            加密后的文件
	 */
	public void P7CryptEncryptFile(int algType, byte[] keyBuf, int keyLen,
			String inputFileName, String outputFileName)
			throws EYIBCException {
		p7cryptEncryptFile(algType, keyBuf, keyLen, inputFileName,
				outputFileName);
	}
	
	/**
	 * 生成SM2密钥对
	 * @param password SM2密钥的保护口令
	 * @param pubKeyBuf 公钥数据
	 * @param pubKeyLen 公钥数据长度
	 * @param prvKeyBuf 私钥数据
	 * @param prvKeyLen 私钥数据长度
	 * @param pSize PSIZE
	 * @param nFormat 格式，保留，请传0
	 * @throws EYIBCException
	 */
	public native void generateSM2KeyPair(String password, byte[]pubKeyBuf, int[] pubKeyLen, byte[]prvKeyBuf, int[] prvKeyLen, int pSize, int nFormat) throws EYIBCException;
	 
	/**
	 * 从内存加载SM2公钥数据
	 * @param pubKeyBuf 公钥数据
	 * @param pubKeyLength 公钥数据长度
	 * @param flag 保留FLAG，请传0
	 * @return 公钥对象
	 * @throws EYIBCException
	 */
	public native long createSM2PubKeyObjectFromMem(byte[] pubKeyBuf, int pubKeyLength, int flag) throws EYIBCException;
	  
	/**
	 * 根据参数对象，创建SM9公钥对象
	 * @param IBCParamCtx 参数对象
	 * @param ID SM9标识
	 * @param alg 算法
	 * @param groupid 群组
	 * @return 公钥对象
	 */
	public native long createSM9PubKeyObject(long IBCParamCtx, byte[]ID, int alg, int groupid);
	
	/**
	 * 从内存创建SM2私钥对象
	 * @param libCtx 全局加密引擎句柄
	 * @param prvKeyBuf 私钥数据
	 * @param prvKeyLen 私钥数据长度
	 * @param password 口令
	 * @param preCompute 是否预计算，0为不进行预计算，当使用此密钥重复大量运算时，预计算可以加快速度 
	 * @return 私钥对象
	 * @throws EYIBCException
	 */
	public native long createSM2PrvKeyObjectFromMem(long libCtx, byte[] prvKeyBuf, int prvKeyLen, String password, int preCompute) throws EYIBCException;
	
	/**
	 * 根据公钥对象加密数据
	 * @param pubKeyCtx 公钥对象
	 * @param inBuf 需要加密的数据
	 * @return 加密后的结果
	 * @throws EYIBCException
	 */
	public native byte[] cryptExportDataEx(long pubKeyCtx, byte[]inBuf) throws EYIBCException;
	  
	/**
	 * 根据私钥对象签名数据
	 * @param prvKeyCtx 私钥对象
	 * @param hashObject 哈希对象
	 * @return 签名后的结果
	 * @throws EYIBCException
	 */
	public native byte[] cryptSignDataEx(long prvKeyCtx, long hashObject) throws EYIBCException;
	
	/**
	 * 根据公钥对象验签哈希对象数据
	 * @param pubKeyCtx 公钥对象
	 * @param signedBuf 签名结果
	 * @param hashObject 哈希对象
	 * @return 1为验签成功。
	 */
	public native int cryptVerifySignDataEx(long pubKeyCtx, byte[] signedBuf, long hashObject);
	
	/**
	 * 根据公钥对象验签原始数据
	 * @param pubKeyCtx 公钥对象
	 * @param signedBuf 签名结果
	 * @param oriData 原始数据
	 * @return 1为验签成功
	 */
	public native int cryptVerifySignDataEx2(long pubKeyCtx, byte[] signedBuf, byte[] oriData);
	
	/**
	 * 计算生成哈希对象
	 * @param inBuf 需要计算哈希的值
	 * @param alg 算法
	 * @return 哈希对象
	 * @throws EYIBCException
	 */
	public native long genHashObject(byte[]inBuf, int alg) throws EYIBCException;
	
	/**
	 * 销毁哈希对象
	 * @param hashObject 哈希对象
	 */
	public native void destroyHashObject(long hashObject);
	  
	/**
	 * 销毁公钥对象
	 * @param pubKeyObject 公钥对象
	 */
	public native void destroyPubKeyObject(long pubKeyObject);
	
	/**
	 * 密钥派生
	 * @param pass 口令
	 * @param passlen 口令长度
	 * @param salt 盐
	 * @param saltlen 盐长度
	 * @param iter 迭代次数
	 * @param prfType 计算类型
	 * @param dklen 密钥派生的长度
	 * @return 密钥派生的结果
	 */
	public native byte[] GMPBKDF2(byte[]pass, int passlen, byte[]salt, int saltlen, int iter, int prfType, int dklen);
	
	/**
	 * 修改SM9私钥文件的密钥
	 * @param fileName 文件名
	 * @param OldPassword 原密码
	 * @param NewPassword 新密码
	 */
	public native void ChangePrvKeyFilePassword(String fileName, String OldPassword, String NewPassword) throws EYIBCException;
	
	/**
	 * 生成SM9主密钥
	 * @param domainName 域
	 * @param serialNum 序列号
	 * @param cType 曲线类型
	 * @param pSize PSIZE
	 * @param rSize RSIZE
	 * @param kga KGA
	 * @param schema SCHEMA
	 * @param paramFile 生成的参数文件名
	 * @param mkfile 生成的主密钥文件名
	 * @param password 口令
	 * @throws EYIBCException
	 */
	public native void GMIBCSSG(String domainName, int serialNum, int cType, int pSize, int rSize, int kga, int schema,
				String paramFile, String mkfile, String password) throws EYIBCException;
	
	/**
	 * 从内存加载主密钥对象
	 * @param mkfile 主密钥文件
	 * @param password 口令
	 * @return 主密钥对象
	 * @throws EYIBCException
	 */
	public native long IBCLoadMasterKeyFromFile(String mkfile, String password)throws EYIBCException;
	
	/**
	 * 使用SM9主密钥对象进行短签名
	 * @param masterkeyCtx 主密钥对象
	 * @param paramCtx 参数对象
	 * @param needSign 需要签名的数据
	 * @param needSignLength 需要签名的数据的长度
	 * @return 签名结果
	 * @throws EYIBCException
	 */
	public native byte[] GMIBCSSS(long masterkeyCtx, long paramCtx, byte[]needSign, int needSignLength)throws EYIBCException;
	
	/**
	 * 使用参数对象进行验签
	 * @param paramCtx 参数对象
	 * @param oriData 原始数据
	 * @param oriDataLength 原始数据长度
	 * @param signedData 签名结果
	 * @param signedDataLength 签名结果长度
	 * @return 1为验签成功
	 * @throws EYIBCException
	 */
	public native int GMIBCSSV(long paramCtx, byte[]oriData, int oriDataLength, byte[]signedData, int signedDataLength)throws EYIBCException;
	
	/**
	 * 短加密
	 * @param paramCtx 参数对象
	 * @param algid 加密算法
	 * @param accountID SM9标识
	 * @param needEnc 需要加密的数据
	 * @param needEncLength 需要加密的数据的长度
	 * @return 加密的结果
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIBEEncEx(long paramCtx, int algid, String accountID, byte[]needEnc, int needEncLength)throws EYIBCException;
	
	/**
	 * 根据主密钥进行短解密
	 * @param masterkeyCtx 主密钥对象
	 * @param paramCtx 参数对象
	 * @param algo 算法
	 * @param accountID SM9标识
	 * @param tmpFileName 临时文件
	 * @param inputData 需要加密的数据
	 * @param inputDataLength 需要加密的数据长度
	 * @return 解密结果
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIBEDecExFromMaster(long masterkeyCtx, long paramCtx, int algo, String accountID, String tmpFileName, byte[] inputData, int inputDataLength) throws EYIBCException;
	
	/**
	 * 初始化EYIBC库，多线程工作时，一定要先进行初始化
	 */
	public static native void initEYIBC();
	
	/**
	 * 设置IBC配置属性
	 * @param iType
	 * @param iValue
	 */
	public native void SetEYIBCIntConfig(int iType, int iValue);

	
	/**
	 * 生成TOKEN
	 * @param secData
	 * @param secDataLength
	 * @return
	 */
	public native int GMOTPToken(byte[] secData, int secDataLength);
	 
	/**
	 * 密钥派生
	 * @param msg
	 * @param msgLen
	 * @param dkLen
	 * @param algType
	 * @return
	 * @throws EYIBCException
	 */
	public native byte[] GMKDF(byte[] msg, int msgLen, int dkLen, int algType) throws EYIBCException;
	
	/**
	 * 对称加密文件，封装成P7结构
	 * @param inputFileName 需要加密的文件
	 * @param outputFileName 加密的文件名
	 * @param keyData 密钥
	 * @param keyLen 密钥长度
	 * @param algType 加密算法
	 * @throws EYIBCException
	 */
	public native void SYMEncFile(String inputFileName, String outputFileName, byte[] keyData, int keyLen, int algType) throws EYIBCException;
	
	/**
	 * 对称解密P7文件
	 * @param inputFileName 需要解密的文件
	 * @param outputFileName 解密后的文件
	 * @param keyData 密钥
	 * @param keyLen 密钥长度
	 * @throws EYIBCException
	 */
	public native void SYMDecFile(String inputFileName, String outputFileName, byte[] keyData, int keyLen) throws EYIBCException;	
	
	/**
	 * CHN密钥协商生成X（客户端）
	 * @param paramCtx 参数对象
	 * @param peerID 对端的标识
	 * @return 生成的TOKENX
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIKEtokenX(long paramCtx, String peerID) throws EYIBCException;
	
	/**
	 * CHN密钥协商生成Y（服务端）
	 * @param paramCtx 参数对象
	 * @param peerID 对端的标识
	 * @return 生成的TOKENY
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIKEtokenY(long paramCtx, String peerID) throws EYIBCException;	
	  
	/**
	 * 密钥协商
	 * @param privateCtx 私钥对象
	 * @param peerID 对端标识
	 * @param clientQ clientQ
	 * @param serverQ serverQ
	 * @param mac MAC值
	 * @return 生成的密钥协商数据
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIKEKEPX(long privateCtx, String peerID, byte[] clientQ, byte[] serverQ, byte[] mac) throws EYIBCException;	
	
	/**
	 * 密钥协商
	 * @param privateCtx 私钥对象
	 * @param peerID 对端标识
	 * @param clientQ clientQ
	 * @param serverQ serverQ
	 * @param mac MAC值
	 * @return 生成的密钥协商数据
	 * @throws EYIBCException
	 */
	public native byte[] GMCHNIKEKEPY(long privateCtx, String peerID, byte[] clientQ, byte[] serverQ, byte[] mac) throws EYIBCException;	
	  
	  /**
	   * CTR模式加密数据
	   * @param key 密钥，SM4,AES128算法，KEY必须为16字节
	   * @param keyLength 密钥长度，SM4,AES128算法，KEY必须为16字节
	   * @param iv IV，SM4,AES128算法，IV必须为16字节， 前12字节为有效内容，后面4字节无作用
	   * @param ivLength IV长度，SM4,AES128算法，IV必须为16字节
	   * @param inputData 需要加密的数据
	   * @param inputDataLength 需要加密的数据的长度
	   * @param nAlg 加密算法
	   * @param offset 偏移
	   * @return 加密后的数据
	   * @throws EYIBCException
	   */
	public native byte[] GMCryptEncryptCTR(byte[] key, int keyLength, byte[] iv, int ivLength, byte[] inputData, int inputDataLength, int nAlg, int offset) throws EYIBCException;
	  
	  /**
	   * CTR模式解密数据
	   * @param key 密钥，SM4,AES128算法，KEY必须为16字节
	   * @param keyLength 密钥长度，SM4,AES128算法，KEY必须为16字节
	   * @param iv IV，SM4,AES128算法，IV必须为16字节， 前12字节为有效内容，后面4字节无作用
	   * @param ivLength IV长度，SM4,AES128算法，KEY必须为16字节
	   * @param inputData 需要解密的数据
	   * @param inputDataLength 需要解密的数据的长度
	   * @param nAlg 加密算法
	   * @param offset 偏移
	   * @return 解密后的数据
	   * @throws EYIBCException
	   */
	public native byte[] GMCryptDecryptCTR(byte[] key, int keyLength, byte[] iv, int ivLength, byte[] inputData, int inputDataLength, int nAlg, int offset) throws EYIBCException;
	  //public native int TESTTOKENKE(String paramFile, String private1, String private2);
	  
	public native byte[] P7Write(long libCtx, long paramObj, String recpList, int alg, byte[] inputData, int inputDataLength);
}
